package com.example.beautyUi

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.LinearGradient
import android.graphics.Paint
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatTextView
import android.graphics.Path
import android.graphics.RadialGradient
import android.graphics.RectF
import android.graphics.Shader
import android.graphics.SweepGradient
import com.example.base.R
import androidx.core.content.withStyledAttributes

/**
 * author：jiazhijie
 * date：2025/10/20
 * desc：自定义tv
 * modify record：
 */
@SuppressLint("Recycle")
class RoundGradientTextView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : AppCompatTextView(context, attrs, defStyleAttr) {

    private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val strokePaint = Paint(Paint.ANTI_ALIAS_FLAG)

    // 路径
    private val path = Path()
    private val rectF = RectF()

    // 圆角半径数组 [topLeft, topRight, bottomRight, bottomLeft]
    private val radiusArray = FloatArray(8)

    // 属性值
    private var cornerRadius = 0f
    private var topLeftRadius = 0f
    private var topRightRadius = 0f
    private var bottomLeftRadius = 0f
    private var bottomRightRadius = 0f

    private var strokeWidth = 0f
    private var strokeColor = Color.TRANSPARENT

    private var gradientStartColor = 0
    private var gradientEndColor = 0
    private var gradientCenterColor = 0
    private var gradientOrientation = 0
    private var gradientType = 0
    private var hasGradient = false

    private var solidColor = Color.TRANSPARENT


    init {
        attrs?.let {
            //obtainStyledAttributes方法可以在xml布局中预览
            //withStyledAttributes方法不可以预览
            val array = context.obtainStyledAttributes(it,R.styleable.RoundGradientTextView)
            array.let {
                cornerRadius = it.getDimension(R.styleable.RoundGradientTextView_cornerRadius, 0f)
                topLeftRadius =
                    it.getDimension(R.styleable.RoundGradientTextView_leftTopRadius, cornerRadius)
                topRightRadius =
                    it.getDimension(R.styleable.RoundGradientTextView_rightTopRadius, cornerRadius)
                bottomLeftRadius =
                    it.getDimension(R.styleable.RoundGradientTextView_leftBottomRadius, cornerRadius)
                bottomRightRadius =
                    it.getDimension(R.styleable.RoundGradientTextView_rightBottomRadius, cornerRadius)
                strokeWidth = it.getDimension(R.styleable.RoundGradientTextView_strokeWidth, 0f)
                strokeColor =
                    it.getColor(R.styleable.RoundGradientTextView_strokeColor, Color.TRANSPARENT)
                // 渐变
                gradientStartColor =
                    it.getColor(R.styleable.RoundGradientTextView_gradientStartColor, 0)
                gradientEndColor = it.getColor(R.styleable.RoundGradientTextView_gradientEndColor, 0)
                gradientCenterColor =
                    it.getColor(R.styleable.RoundGradientTextView_gradientCenterColor, 0)
                gradientOrientation =
                    it.getInt(R.styleable.RoundGradientTextView_gradientOrientation, 0)
                gradientType = it.getInt(R.styleable.RoundGradientTextView_gradientType, 0)
                hasGradient = gradientStartColor != 0 && gradientEndColor != 0
                // 纯色背景
                solidColor =
                    it.getColor(R.styleable.RoundGradientTextView_solidColor, Color.TRANSPARENT)
            }

            array.recycle()

        }



        setPaints()
        updateRadiusArray()

    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        // 尺寸改变时重新设置渐变
        if (hasGradient) {
            setupGradient()
        }
    }

    private fun setPaints(){
        backgroundPaint.style = Paint.Style.FILL
        strokePaint.style = Paint.Style.STROKE
        strokePaint.strokeWidth = strokeWidth
        strokePaint.color = strokeColor
    }

    private fun updateRadiusArray() {
        // 每个角需要两个值 (x半径, y半径)
        radiusArray[0] = topLeftRadius
        radiusArray[1] = topLeftRadius
        radiusArray[2] = topRightRadius
        radiusArray[3] = topRightRadius
        radiusArray[4] = bottomRightRadius
        radiusArray[5] = bottomRightRadius
        radiusArray[6] = bottomLeftRadius
        radiusArray[7] = bottomLeftRadius
    }


    private fun setupGradient() {
        val shader: Shader = when (gradientType) {
            0 -> createLinearGradient() // 线性渐变
            1 -> createRadialGradient() // 径向渐变
            2 -> createSweepGradient()  // 扫描渐变
            else -> createLinearGradient()
        }
        backgroundPaint.shader = shader
    }

    private fun createLinearGradient(): LinearGradient {
        val colors = if (gradientCenterColor != 0) {
            intArrayOf(gradientStartColor, gradientCenterColor, gradientEndColor)
        } else {
            intArrayOf(gradientStartColor, gradientEndColor)
        }

        return when (gradientOrientation) {
            0 -> LinearGradient(0f, 0f, 0f, height.toFloat(), colors, null, Shader.TileMode.CLAMP) // 上到下
            1 -> LinearGradient(0f, 0f, width.toFloat(), 0f, colors, null, Shader.TileMode.CLAMP) // 左到右
            2 -> LinearGradient(0f, 0f, width.toFloat(), height.toFloat(), colors, null, Shader.TileMode.CLAMP) // 左上到右下
            3 -> LinearGradient(0f, height.toFloat(), width.toFloat(), 0f, colors, null, Shader.TileMode.CLAMP) // 左下到右上
            else -> LinearGradient(0f, 0f, 0f, height.toFloat(), colors, null, Shader.TileMode.CLAMP)
        }
    }


    private fun createRadialGradient(): RadialGradient {
        val colors = if (gradientCenterColor != 0) {
            intArrayOf(gradientStartColor, gradientCenterColor, gradientEndColor)
        } else {
            intArrayOf(gradientStartColor, gradientEndColor)
        }

        val centerX = width / 2f
        val centerY = height / 2f
        val radius = width.coerceAtLeast(height) / 2f

        return RadialGradient(centerX, centerY, radius, colors, null, Shader.TileMode.CLAMP)
    }

    private fun createSweepGradient(): SweepGradient {
        val colors = if (gradientCenterColor != 0) {
            intArrayOf(gradientStartColor, gradientCenterColor, gradientEndColor)
        } else {
            intArrayOf(gradientStartColor, gradientEndColor)
        }

        val centerX = width / 2f
        val centerY = height / 2f

        return SweepGradient(centerX, centerY, colors, null)
    }

    override fun onDraw(canvas: Canvas) {
        // 绘制背景和边框
        drawBackground(canvas)
        drawStroke(canvas)

        // 调用父类绘制文本
        super.onDraw(canvas)
    }


    private fun drawBackground(canvas: Canvas){

        if (!hasGradient || solidColor!=Color.TRANSPARENT){
            backgroundPaint.color = solidColor
        }

        path.reset()
        rectF.set(
            strokeWidth / 2,
            strokeWidth / 2,
            width - strokeWidth / 2,
            height - strokeWidth / 2
        )
        path.addRoundRect(rectF, radiusArray, Path.Direction.CW)
        // 绘制背景
        canvas.drawPath(path, backgroundPaint)
    }

    private fun drawStroke(canvas: Canvas) {
        if (strokeWidth > 0 && strokeColor != Color.TRANSPARENT) {
            // 创建圆角矩形路径（边框路径）
            path.reset()
            rectF.set(
                strokeWidth / 2,
                strokeWidth / 2,
                width - strokeWidth / 2,
                height - strokeWidth / 2
            )
            path.addRoundRect(rectF, radiusArray, Path.Direction.CW)

            // 绘制边框
            canvas.drawPath(path, strokePaint)
        }
    }

    // 提供动态设置方法
    fun setCornerRadius(radius: Float) {
        this.cornerRadius = radius
        this.topLeftRadius = radius
        this.topRightRadius = radius
        this.bottomLeftRadius = radius
        this.bottomRightRadius = radius
        updateRadiusArray()
        invalidate()
    }


    fun setStroke(width: Float, color: Int) {
        this.strokeWidth = width
        this.strokeColor = color
        strokePaint.strokeWidth = width
        strokePaint.color = color
        invalidate()
    }

    fun setGradient(startColor: Int, endColor: Int, centerColor: Int = 0, orientation: Int = 0) {
        this.gradientStartColor = startColor
        this.gradientEndColor = endColor
        this.gradientCenterColor = centerColor
        this.gradientOrientation = orientation
        this.hasGradient = true
        setupGradient()
        invalidate()
    }

    fun setSolidColor(color: Int) {
        this.solidColor = color
        this.hasGradient = false
        backgroundPaint.shader = null
        invalidate()
    }




}